#include<cstdio>//uncle-lu
#include<cstring>
#include<algorithm>
template<class T>
void read(T &x)
{
	x=0;bool f=false;char ch=getchar();
	while(ch<'0'||ch>'9') { f|=(ch=='-'); ch=getchar(); }
	while(ch<='9'&&ch>='0') { x = (x<<1) + (x<<3) + (ch^48); ch=getchar(); }
	x = f ? -x : x;
	return ;
}

void DFS(int);
bool check(int, int);

struct node{
	int son[2];
	int val;
};

int n,ans=1;
node U[1000010];
bool is_[1000010];
int count[1000010];

bool check(int x, int y)
{
	if(x==-1 && y==-1)
		return true;
	if(x==-1 || y==-1 || U[x].val != U[y].val)
		return false;

	if( ( !check(U[x].son[0], U[y].son[1]) ) || ( !check(U[x].son[1], U[y].son[0]) ) )
		return false;

	return true;
}

void DFS(int x)
{
	if(U[x].son[0] == -1 && U[x].son[1] == -1)
	{
		is_[x] = true;
		count[x] = 1;
		return ;
	}

	if(U[x].son[0]!=-1)
	{
		DFS(U[x].son[0]);
		count[x] += count[U[x].son[0]];
	}
	if(U[x].son[1]!=-1)
	{
		DFS(U[x].son[1]);
		count[x] += count[U[x].son[1]];
	}
	count[x]++;

	if(check(U[x].son[0], U[x].son[1]))
	{
		is_[x] = true;
		ans = std::max(ans, count[x]);
	}
	else
	{
		is_[x] = false;
	}
	return ;
}

int main()
{
	int a,b;
	read(n);
	for(int i=1;i<=n;++i)
		read(U[i].val);

	for(int i=1;i<=n;++i)
	{
		read(a);read(b);
		U[i].son[0] = a;
		U[i].son[1] = b;
	}

	DFS(1);

	printf("%d",ans);

	return 0;
}
